<?php
define("EQUALS", "=");
define("NOT_EQUALS", "<>");
define("LIKE", "like");
define("LEFT_LIKE", "llike");
define("RIGHT_LIKE", "rlike");
define("NOT_LIKE", "not like");
define("IN", "in");
define("NOT_IN", "not in");
define("LESSTHEN", "<");
define("LESSTHEN_OR_EQUALS", "<=");
define("MORETHEN", ">");
define("MORETHEN_OR_EQUALS", ">=");
class SqlFilter {
    protected $op_map = array();
    public $value_map = array();
    public $fieldlist = array();
    public $valuelist = array();
    public $params = array();
    public $attach_express = "";
    public function SqlFilter($key = null, $op = null, $value = null) {
        if ($key != null && !empty($key) && !empty($op) && !empty($value)) {
            $this->addFilter($key, $op, $value);
        }
    }

    public function addFilter($key, $op, $value) {
        if ($value != null && $value != "") {
            $count = $this->getSameNameFieldCount($key);
            if ($count > 0) {
                $key = $key . "^" . ($count);
            }
            $_op = strtolower(trim($op));
            //$value = iconv('utf-8','gb2312',$value);
            if ($_op == "like") {
                $value = "%" . $value . "%";
            } else if ($_op == "llike") {
                $value = $value . "%";
            } else if ($_op == "rlike") {
                $value = "%" . $value;
            }
            $this->op_map[$key] = $op;
            $this->value_map[$this->getField($key) ] = $value;
            $this->params[":" . $this->getField($key) ] = $value;
            array_push($this->fieldlist, $key);
            array_push($this->valuelist, $value);
        }
        return $this;
    }

    public function addExpress($express) {
        $spit = strstr($express, "and") == false ? " and " : " ";
        $this->attach_express.= $spit . $express;
        return $this;
    }

    public function containsField($key) {
        return array_key_exists($this->getField($key), $this->value_map);
    }

    public function getField($field) {
        $arr = explode(".", $field);
        if (count($arr) > 1) {
            $field = $arr[1];
        }
        return $field;
    }

    public function getValue($key) {
        return $this->value_map[$this->getField($key) ];
    }

    public function toSqlExpress() {
        $strEpress = "";
        try {
            $keys = array_keys($this->op_map);
            for ($i = 0;$i < count($this->value_map);$i++) {
                $key = $keys[$i];
                //$field =  $this->getField($key);
                $field = $key;
                $op = $this->op_map[$key];
                $value = $this->value_map[$this->getField($key) ];
                //$value = $this->value_map[$field];
                $match = array();
                if ($value != null && $value != "") {
                    $spit = $strEpress == "" ? "" : " AND ";
                    if (preg_match('/(\^\d+)?/', $field, $match)) {
                        $field = preg_replace('/(\^\d+)?/', '', $field);
                    }
                    //$strEpress.= $spit . $field . " " . $op . ":" . $key;
                    // $strEpress.= $field . " " . $op . " :" .  $key;
                    $strEpress.= $spit . $field . " " . $op . " ?";
                }
            }
            $this->attach_express = trim($this->attach_express);
            if ($this->attach_express != "") {
                if ($strEpress == "" && substr($this->attach_express, 0, 3) == "and") {
                    $this->attach_express = substr($this->attach_express, 3);
                }
                $strEpress.= " " . $this->attach_express;
            }
        }
        catch(Exception $ex) {
            $ex->getMessage();
        }
        return $strEpress;
    }
    
    private function getSameNameFieldCount($field) {
        $count = 0;
        $keys = array_keys($this->value_map);
        for ($i = 0;$i < count($keys);$i++) {
            $f = $keys[$i];
            if (preg_match('/' . $field . '(\^\d+)?/', $f, $match)) {
                $count++;
            }
        }
        return $count;
    }
}
?>
